package com.excilys.formation.project.repository;

import java.util.List;
import java.util.Map;

import javax.validation.constraints.Min;

import org.joda.time.Interval;

import com.excilys.formation.project.entities.Operation;
import com.excilys.formation.project.entities.TypeOperation;

/**
 * Interface d'accès aux opérations.
 * 
 * @author excilys
 * 
 */
public interface OperationDAO {

	/**
	 * Renvoie les opérations d'un certain type d'un compte donné dans un interval de temps.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param interval
	 *            Interval de dates pour récupérer les opérations
	 * @param offset
	 *            numéro du premier résultat à récupérer
	 * @param limit
	 *            nombre de résultat à récupérer
	 * @param type
	 *            Type d'opérations à récupérer
	 * @return les opérations d'un compte donné.
	 */
	List<Operation> getOperationsByCompteAndTimeIntervalAndType(String compteNumero, Interval interval, TypeOperation type,
			@Min(0) int offset, @Min(0) int limit);

	/**
	 * Renvoie le nombre d'opérations d'un certain type d'un compte donné dans un interval de temps.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param interval
	 *            Interval de dates pour récupérer les opérations
	 * @param type
	 *            Type d'opérations à récupérer
	 * @return le nombre d'opérations d'un compte donné.
	 */
	long getCountOperationsByCompteAndTimeIntervalAndType(String compteNumero, Interval interval, TypeOperation type);

	/**
	 * Renvoie les opérations d'un compte donné dans un interval de temps à l'exception des opérations d'un certain type.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param interval
	 *            Interval de dates pour récupérer les opérations
	 * @param type
	 *            Type d'opérations à exclure
	 * @param offset
	 *            numéro du premier résultat à récupérer
	 * @param limit
	 *            nombre de résultat à récupérer
	 * @return les opérations d'un compte donné.
	 */
	List<Operation> getOperationsByCompteAndTimeIntervalExceptType(String compteNumero, Interval interval, TypeOperation type,
			@Min(0) int offset, @Min(0) int limit);

	/**
	 * Renvoie le nombre d'opérations d'un compte donné dans un interval de temps à l'exception des opérations d'un certain type.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param interval
	 *            Interval de dates pour récupérer les opérations
	 * @param type
	 *            Type d'opérations à exclure
	 * @return le nombre d'opérations d'un compte donné.
	 */
	long getCountOperationsByCompteAndTimeIntervalExceptType(String compteNumero, Interval interval, TypeOperation type);

	/**
	 * Renvoie la somme du montant des opérations d'un type donné dans un interval de temps.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut sommer les montants des opérations
	 * @param interval
	 *            Interval de dates pour sommer les montants des opérations
	 * @param type
	 *            Type d'opérations dont il faut sommer les montants
	 * @return les opérations d'un compte donné.
	 */
	double getSumOperationsByCompteAndTimeIntervalAndType(String compteNumero, Interval interval, TypeOperation type);

	/**
	 * Persiste une nouvelle opération ou les changements d'une existante.
	 * 
	 * @param operation
	 *            l'opération à persister.
	 */
	void save(Operation operation);

	/**
	 * Renvoie la somme du montant des opérations d'un type donné dans un interval de temps.
	 * 
	 * @param clientId
	 *            Le numéro du compte dont il faut sommer les montants des opérations
	 * @return La somme de l'encours pour chaque compte.
	 */
	Map<String, Double> getSumEncoursByClient(long clientId);

	/**
	 * Renvoie le TypeOperation correspondant à l'id en base.
	 * 
	 * @param id
	 *            L'id du type à renvoyer
	 * @return Le type
	 */
	TypeOperation getTypeByID(int id);

}
